/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include "引擎数据类型.h"
#include "引擎枚举数据.h"
#include "设备内存缓存.h"


#include <字符串数值互换.h>
#include <list>



struct S_列表填充数据 {
	std::u16string				m_ico;
	S_RGBA8UI					m_ico_color;
	std::vector<std::u16string>	m_item;
	std::vector<int32>			m_itemID;
	
	int32						m_ID_X;
	int32						m_ID_Y;

	void*	m_Data;
	uint64	m_DataType;
	bool	m_激活;
};

typedef bool(*fp_列表项选中回调)(C_Widget* self, const S_列表填充数据& item);


Inline S_Props f_prop_引用(S_Props& p) {
	S_Props 属性 = p;
	DEF_alloc_Props_UI_Ptr(属性);

	(*属性.m_UI) = (*p.m_UI);
	属性.m_值映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	return 属性;
}





inline S_Props f_alloc_BoolProp(bool* value, std::u16string name, bool 默认值 = false) {
	E_属性值映射方式 值映射类型;
	if (value == nullptr) {
		value = (bool*)malloc(sizeof(bool));
		(*value) = 默认值;
		值映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		值映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	S_Props prop = f_prop_init(E_值类型::e_Type_Bool, value, name, 值映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

struct S_PropVecBool{
	std::string		m_ICO;
	std::wstring	m_Names;
	bool			m_Value;
};

struct S_PropVecU8{
	std::string		m_ICO;
	std::wstring	m_Names;
	uint8			m_Value;
};


Inline bool& f_prop_Bool(S_Props& prop) {
	return *((bool*)prop.m_Value);
}

Inline const bool& f_prop_Bool(const S_Props& prop) {
	return *((bool*)prop.m_Value);
}



inline S_Props f_alloc_F32Prop(float32* value, std::u16string name, float32 初始值 = 1.0, float32 min = -3.4E38, float32 max = +3.4E38) {
	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = (float32*)malloc(sizeof(float32));
		(*value) = 初始值;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	S_Props prop = f_prop_init(E_值类型::e_Type_F32, value, name, 映射类型);
	prop.m_值映射类型 = 映射类型;
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline float32& f_prop_F32(S_Props& prop) {
	return *((float32*)prop.m_Value);
}
Inline const float32& f_prop_F32(const S_Props& prop) {
	return *((float32*)prop.m_Value);
}





Inline S_Props f_alloc_UI32FlagBitsProp(uint32* data, std::u16string name) {
	E_属性值映射方式 映射类型;
	if(!data) {
		data = (uint32*)malloc(sizeof(uint32));
		(*data) = 0;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	
	S_Props prop = f_prop_init(E_值类型::e_Type_UI32_FlagBits, data, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}


Inline S_Props f_alloc_bool_1DProp(uint8 num, std::u16string name, uint8 min = 0, uint8 max = 255) {
	S_PropVecBool* e = new S_PropVecBool[num];
	for (uint32 i = 0; i < num; ++i) {
		e[i].m_Value = false;
	}
	
	S_Props prop = f_prop_init(E_值类型::e_Type_Bool_1D, e, name, E_属性值映射方式::e_属性值映射_独立创建);
	prop.m_值元素个数 = num;
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_Props f_alloc_u8_1DProp(uint8 num, std::u16string name, uint8 min = 0, uint8 max = 255) {
	S_PropVecU8* e = new S_PropVecU8[num];
	for (uint32 i = 0; i < num; ++i) {
		e[i].m_Value = i;
	}
	
	S_Props prop = f_prop_init(E_值类型::e_Type_UI8_Array1D, e, name, E_属性值映射方式::e_属性值映射_独立创建);
	prop.m_值元素个数 = num;
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}



Inline S_Props f_alloc_iVec3Prop(ivec3* data, std::u16string name, int32 min = 0xffffffff, int32 max = 0x0fffffff) {
	E_属性值映射方式 映射类型;
	if (data == nullptr) {
		data = (ivec3*)malloc(sizeof(ivec3));
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	
	S_Props prop = f_prop_init(E_值类型::e_Type_iVec3, data, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}
Inline ivec3& f_prop_iVec3(S_Props& prop) {
	return *((ivec3*)prop.m_Value);
}



Inline S_Props f_alloc_uVec3Prop(uvec3* data, std::u16string name, float32 min = -3.4E38, float32 max = +3.4E38) {
	E_属性值映射方式 映射类型;
	if (data == nullptr) {
		data = (uvec3*)malloc(sizeof(uvec3));
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	
	S_Props prop = f_prop_init(E_值类型::e_Type_uVec3, data, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}
Inline uvec3& f_prop_uvec3(S_Props& prop) {
	return *((uvec3*)prop.m_Value);
}



inline S_Props f_alloc_Vec4Prop(vec4* data, std::u16string name, float32 min = -3.4E38, float32 max = +3.4E38) {
	E_属性值映射方式 映射类型;
	if (data == nullptr) {
		data = (vec4*)malloc(sizeof(vec4));
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	
	S_Props prop = f_prop_init(E_值类型::e_Type_Vec4, data, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}
Inline vec4& f_prop_Vec4(S_Props& prop) {
	return *((vec4*)prop.m_Value);
}
Inline const vec4& f_prop_Vec4(const S_Props& prop) {
	return *((vec4*)prop.m_Value);
}



Inline S_Props f_alloc_iVec4Prop(ivec4* data, std::u16string name, uint32 min = 0, uint32 max = 0xffffffff) {
	E_属性值映射方式 映射类型;
	if (data == nullptr) {
		data = (ivec4*)malloc(sizeof(ivec4));
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	
	S_Props prop = f_prop_init(E_值类型::e_Type_iVec4, data, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}
Inline ivec4& f_prop_iVec4(S_Props& prop) {
	return *((ivec4*)prop.m_Value);
}



Inline S_Props f_alloc_uVec4Prop(uvec4* data, std::u16string name, int32 min = 0xffffffff, int32 max = 0x0fffffff) {
	E_属性值映射方式 映射类型;
	if (data == nullptr) {
		data = (uvec4*)malloc(sizeof(uvec4));
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	
	S_Props prop = f_prop_init(E_值类型::e_Type_uVec4, data, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}
Inline uvec4& f_prop_uVec4(S_Props& prop) {
	return *((uvec4*)prop.m_Value);
}



Inline int8& f_prop_I8(S_Props& prop) {
	return *((int8*)prop.m_Value);
}
Inline const int8& f_prop_I8(const S_Props& prop) {
	return *((int8*)prop.m_Value);
}

Inline uint8& f_prop_UI8(S_Props& prop) {
	return *((uint8*)prop.m_Value);
}

Inline const uint8& f_prop_UI8(const S_Props& prop) {
	return *((uint8*)prop.m_Value);
}
Inline S_PropVecU8* f_prop_UI8_1D(S_Props& prop) {
	return ((S_PropVecU8*)prop.m_Value);
}

Inline S_PropVecBool* f_prop_Bool_1D(S_Props& prop) {
	return ((S_PropVecBool*)prop.m_Value);
}
Inline const S_PropVecBool* f_prop_Bool_1D(const S_Props& prop) {
	return ((S_PropVecBool*)prop.m_Value);
}


Inline int16& f_prop_I16(S_Props& prop) {
	return *((int16*)prop.m_Value);
}

Inline uint16& f_prop_UI16(S_Props& prop) {
	return *((uint16*)prop.m_Value);
}

Inline const uint16& f_prop_UI16(const S_Props& prop) {
	return *((uint16*)prop.m_Value);
}

Inline int32& f_prop_I32(S_Props& prop) {
	return *((int32*)prop.m_Value);
}

Inline const int32& f_prop_I32(const S_Props& prop) {
	return *((int32*)prop.m_Value);
}


Inline uint32& f_prop_UI32(S_Props& prop) {
	return *((uint32*)prop.m_Value);
}

Inline const uint32& f_prop_UI32(const S_Props& prop) {
	return *((uint32*)prop.m_Value);
}

Inline int64& f_prop_I64(S_Props& prop) {
	return *((int64*)prop.m_Value);
}
Inline uint64& f_prop_UI64(S_Props& prop) {
	return *((uint64*)prop.m_Value);
}


inline vec2& f_prop_Vec2(S_Props& prop) {
	return *((vec2*)prop.m_Value);
}
inline const vec2& f_prop_Vec2(const S_Props& prop) {
	return *((vec2*)prop.m_Value);
}




Inline int32& f_prop_enum(S_Props& prop) {
	return *(((S_PropValueEnum*)prop.m_Value)->m_当前选项);
}
Inline const int32& f_prop_enum(const S_Props& prop) {
	return *(((S_PropValueEnum*)prop.m_Value)->m_当前选项);
}
Inline S_PropValueEnum& f_prop_enumItem(S_Props& prop) {
	return *(((S_PropValueEnum*)prop.m_Value));
}

Inline std::u16string& f_prop_enumName(S_Props& prop) {
	return (((S_PropValueEnum*)prop.m_Value)->m_Names[f_prop_enum(prop)]);
}
Inline const std::u16string& f_prop_enumName(const S_Props& prop) {
	return (((S_PropValueEnum*)prop.m_Value)->m_Names[f_prop_enum(prop)]);
}

Inline void f_release_EnumProp(S_Props& prop) {
	if(((S_PropValueEnum*)prop.m_Value)->m_ICO)		delete[](((S_PropValueEnum*)prop.m_Value)->m_ICO);
	if(((S_PropValueEnum*)prop.m_Value)->m_Names)	delete[](((S_PropValueEnum*)prop.m_Value)->m_Names);
}

Inline S_Props f_alloc_EnumProp(int32* value, const std::vector<S_标题和图标>& icos, std::u16string name, uint8 默认选项 = 0, fp_PropUpdate fn_update = nullptr, bool 是否展开 = true) {
	S_PropValueEnum* e = (S_PropValueEnum*)malloc(sizeof(S_PropValueEnum));

	E_属性值映射方式 映射类型;
	if (value == nullptr) {
		value = (int32*)malloc(sizeof(int32));
		(*value) = 0;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
		(*value) = 默认选项;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}

	e->m_当前选项 = value;
	e->m_展开 = 是否展开;


	uint32 num = icos.size();
	e->m_ICO = new std::u16string[num];
	e->m_Names = new std::u16string[num];
	for (uint32 i = 0; i < num; ++i) {
		e->m_Names[i] = icos[i].m_标题;
		e->m_ICO[i] = icos[i].m_图标;
	}
	//S_Props prop = { E_值类型::e_Type_Enum, (S_结构对象指针)e, name, {}, nullptr, {nullptr}, num, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_Enum, e, name, 映射类型);
	prop.m_值元素个数 = num;
	DEF_alloc_Props_UI_Ptr(prop);
	prop.m_UI->m_Update = fn_update;
	return prop;
}


void f_prop_Release(S_Props& prop);



typedef struct {
	std::u16string*	m_ICO;
	std::u16string*	m_Names;
	uint32			m_数量;
	uint8			m_展开;
}S_Prop枚举项;

typedef struct {
	const S_Prop枚举项*	m_Item;
	uint32*				m_位域;
}S_Prop位域枚举UI32;

Inline S_Prop枚举项* f_Prop位域枚举_项填充(const std::vector<S_标题和图标>& 标题和图标) {
	S_Prop枚举项* item = (S_Prop枚举项*)malloc(sizeof(S_Prop枚举项));

	uint32 num = 标题和图标.size();

	item->m_ICO = new std::u16string[num];
	item->m_Names = new std::u16string[num];
	item->m_展开 = true;
	item->m_数量 = num;

	for (uint32 i = 0; i < num; ++i) {
		item->m_Names[i] = 标题和图标[i].m_标题;
		item->m_ICO[i] = 标题和图标[i].m_图标;
	}

	return item;
}

Inline void f_Prop位域枚举_项销毁(S_Prop枚举项* 项) {
	delete[] 项->m_ICO;
	delete[] 项->m_Names;

	free(项);
}

Inline uint32 f_Prop位域枚举项数量(S_Prop位域枚举UI32* e) {
	return e->m_Item->m_数量;
	//return e->m_Item->m_ICO->size();
}

inline S_Props f_alloc_FlagBitsEnumProp(uint32* data, const S_Prop枚举项& e, std::u16string name, uint32 默认选项 = 0, fp_PropUpdate fn_update = nullptr, bool 是否展开 = true) {
	S_Prop位域枚举UI32* item = (S_Prop位域枚举UI32*)malloc(sizeof(S_Prop位域枚举UI32));
	item->m_Item = &e;
	
	E_属性值映射方式 映射类型;
	if (data == nullptr) {
		data = (uint32*)malloc(sizeof(uint32));
		(*data) = 默认选项;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	S_Props prop = f_prop_init(E_值类型::e_Type_UI32位域枚举, item, name, 映射类型);
	prop.m_值元素个数 = f_Prop位域枚举项数量(item);
	item->m_位域 = data;
	

	DEF_alloc_Props_UI_Ptr(prop);
	prop.m_UI->m_Update = fn_update;
	
	return prop;
}
inline S_Props f_alloc_Prop多按钮(uint32* data, const S_Prop枚举项& e, std::u16string name, uint32 默认选项 = 0, fp_PropUpdate fn_update = nullptr, bool 是否展开 = true) {
	S_Prop位域枚举UI32* item = (S_Prop位域枚举UI32*)malloc(sizeof(S_Prop位域枚举UI32));
	item->m_Item = &e;
	
	E_属性值映射方式 映射类型;
	if (data == nullptr) {
		data = (uint32*)malloc(sizeof(uint32));
		(*data) = 0;
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	S_Props prop = f_prop_init(E_值类型::e_Type_UI32Ops, item, name, 映射类型);
	prop.m_值元素个数 = f_Prop位域枚举项数量(item);

	item->m_位域 = data;
	(*item->m_位域) = 默认选项;

	DEF_alloc_Props_UI_Ptr(prop);
	prop.m_UI->m_Update = fn_update;

	return prop;
}
Inline const S_Prop枚举项& f_prop_位域枚举项(const S_Props& prop) {
	return *(((S_Prop位域枚举UI32*)prop.m_Value)->m_Item);
}
Inline const S_Prop枚举项& f_prop_位域枚举项(S_Props& prop) {
	return *(((S_Prop位域枚举UI32*)prop.m_Value)->m_Item);
}
Inline uint32& f_prop_UI32位域枚举(S_Props& prop) {
	return *(((S_Prop位域枚举UI32*)prop.m_Value)->m_位域);
}
Inline const uint32& f_prop_UI32位域枚举(const S_Props& prop) {
	return *(((S_Prop位域枚举UI32*)prop.m_Value)->m_位域);
}
EngineAPI_EXPORT std::vector<std::u16string> f_prop_EnumItem_Names(const S_Props& prop);



EngineAPI_EXPORT S_Props f_alloc_FlagBitsUI8Prop(uint8* data, std::u16string name, uint8 默认选项 = 0, fp_PropUpdate fn_update = nullptr, bool 是否展开 = true);
Inline const uint8& f_prop_U8位域(const S_Props& prop) {
	return *(((uint8*)prop.m_Value));
}
Inline uint8& f_prop_U8位域(S_Props& prop) {
	return *(((uint8*)prop.m_Value));
}




Inline S_Props f_alloc_BoundProp(S_Cube* data, std::u16string name) {
	E_属性值映射方式 映射类型;
	if (data == nullptr) {
		data = (S_Cube*)malloc(sizeof(S_Cube));
		映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}
	S_Props prop = f_prop_init(E_值类型::e_Type_UI32Ops, data, name, 映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}
Inline uvec4& f_prop_Bound(S_Props& prop) {
	return *((uvec4*)prop.m_Value);
}




std::u16string	f_core_get属性到文本(S_Props prop, uint8 分量 = 0);
void			f_core_字符串转换到属性(S_Props& prop, const std::u16string& text, uint8 分量 = 0);







typedef enum : int32 {
	e_项名称改变 = -3,
	e_项删除 = -2,
	e_项添加 = -1,
	e_项选择 = 0,
}E_Prop_MapPtr_项事件类型;

struct S_MapPtrItem {
	void* m_Ptr;
	std::u16string	m_Str;
	std::u16string	m_Ico;
};

typedef void(*fp_MapPtr元素更新)(S_Props& prop, struct S_MapPtr& self, int32 操作类型);

struct S_MapPtr {
	std::vector<S_MapPtrItem>&	m_PtrItem;
	uint64				m_当前项;
	fp_MapPtr元素更新	mf_元素变更;

	S_MapPtr(std::vector<S_MapPtrItem>& item) : m_PtrItem(item) {}
};

Inline S_MapPtr& f_prop_MapPrt(S_Props& prop) {
	return *((S_MapPtr*)prop.m_Value);
}
Inline uint32 f_prop_MatPtr_切换ID(S_Props& prop, void* ptr) {
	auto& e = *((S_MapPtr*)prop.m_Value);
	auto* data = e.m_PtrItem.data();
	uint32 num = e.m_PtrItem.size();
	for (uint32 i = 0; i < num; ++i) {
		if (data[i].m_Ptr == ptr) {
			e.m_当前项 = i;
			break;
		}
	}
	return e.m_当前项;
}

Inline S_Props f_alloc_StrIndexProp(std::vector<S_MapPtrItem>& item, std::u16string name) {
	S_MapPtr* e = new S_MapPtr(item);
	(*e).m_当前项 = 0;
	(*e).mf_元素变更 = nullptr;
	
	S_Props prop = f_prop_init(E_值类型::e_Type_MapPtr_Array1D, e, name, E_属性值映射方式::e_属性值映射_独立创建);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline void f_StrIndexProp_release(S_Props& prop) {
	S_MapPtr& e = f_prop_MapPrt(prop);
	e.m_PtrItem.clear();
}




//struct S_映射引用项 {
//	void* m_Ptr;
//	std::wstring	m_Str;
//	std::string		m_Ico;
//};

typedef void(*fp_映射引用2D_元素更新)(S_Props& prop, struct S_MapPtr& self, int32 操作类型);

struct S_映射引用2D {
	std::vector<std::vector<S_MapPtrItem>*>& m_PtrItem;
	uvec2									 m_当前项;
	fp_列表项选中回调					     mf_元素选择;
	fp_列表项选中回调					     mf_元素添加;
	fp_列表项选中回调					     mf_元素修改;

	S_映射引用2D(std::vector<std::vector<S_MapPtrItem>*>& item) : m_PtrItem(item) {}
};

Inline S_Props f_alloc_MatPtr2DProp(std::vector<std::vector<S_MapPtrItem>*>& item, std::u16string name) {
	S_映射引用2D* e = new S_映射引用2D(item);
	(*e).m_当前项 = { 0,0 };
	(*e).mf_元素选择 = nullptr;
	(*e).mf_元素添加 = nullptr;
	(*e).mf_元素修改 = nullptr;

	//S_Props prop = { E_值类型::e_Type_映射引用_2D, (S_结构对象指针)e, name, {}, {nullptr}, 0, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_映射引用_2D, e, name, E_属性值映射方式::e_属性值映射_独立创建);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_映射引用2D& f_prop_映射引用2D(S_Props& prop) {
	return *((S_映射引用2D*)prop.m_Value);
}
Inline S_MapPtrItem& f_prop_get2D映射引用项(S_Props& prop, const uvec2& id) {
	auto& e = (*((S_映射引用2D*)prop.m_Value)).m_PtrItem;
	if (e[id.x]->size()) {
		uint32 y = DEF_Min((e[id.x])->size() - 1, id.y);
		return (e[id.x])->at(y);
	}
	else {
		static S_MapPtrItem t{};
		return t;
	}
}

Inline void f_prop_映射引用2D_release(S_Props& prop) {
	delete& f_prop_映射引用2D(prop);

}




Inline S_属性* f_prop_alloc_Str() {
	S_Props* prop = (S_Props*)calloc(1, sizeof(S_Props));
	prop->m_Value = (S_结构指针)new std::u16string;
	prop->m_Type = E_值类型::e_Type_LineText;
	return (S_属性*)prop;
}
Inline void f_prop_free_Str(S_属性* 属性) {
	S_Props* prop = (S_Props*)属性;
	delete (std::u16string*)(prop->m_Value);
	free(属性);
}


struct S_ObjectItem {
	struct S_Object*	当前对象;
	std::u16string		当前选项;
};

struct S_MapObject {
	std::map<std::u16string, struct S_Object*>* 容器;
	S_ObjectItem								当前项;
};
S_Props f_alloc_Object(std::map<std::u16string, struct S_Object*>* data, const std::u16string& name, const std::u16string& 当前项 = u"");

Inline S_MapObject* f_prop_ObjectMap(const S_Props& prop) {
	return ((S_MapObject*)prop.m_Value);
}
void f_prop_ObjectMapSelect(S_Props& prop, const std::u16string& key);

Inline std::u16string& f_prop_ObjectMapKey(const S_Props& prop) {
	return f_prop_ObjectMap(prop)->当前项.当前选项;
}
Inline void f_prop_ObjectMat(S_Props& prop, std::map<std::u16string, struct S_Object*>* data) {
	auto* m = f_prop_ObjectMap(prop);
	m->容器 = data;
}


struct S_ObjectArray {
	std::vector<struct S_Object*>*	容器;
	S_ObjectItem					当前项;
};
S_Props f_alloc_ObjectArray(std::vector<struct S_Object*>* data, const std::u16string& name, struct S_Object* 当前项 = nullptr);
Inline const S_ObjectArray* f_prop_ObjectArray(const S_Props& prop) {
	return ((const S_ObjectArray*)prop.m_Value);
}
Inline S_ObjectArray* f_prop_ObjectArray(S_Props& prop) {
	return ((S_ObjectArray*)prop.m_Value);
}
void f_prop_ObjectArraySelect(S_Props& prop, const std::u16string& key);


struct S_Object*		f_prop_Object(S_Props& prop);
const struct S_Object*	f_prop_Object(const S_Props& prop);

struct S_ObjectItem&	f_prop_ObjectItem(S_Props& prop);
void					f_prop_ObjectSelect(S_Props& prop, const std::u16string& key);




Inline void f_prop_合并行字符串(S_Props& 目标, const S_Props& 源) {
	f_prop_LineStr(目标) += f_prop_LineStr(源);
}
Inline void f_prop_赋值行字符串(S_Props& 目标, const S_Props& 源) {
	f_prop_LineStr(目标) = f_prop_LineStr(源);
}

Inline int32 f_prop_行字符串转整数(const S_Props& prop) {
	return f_字符串转I32(f_prop_LineStr(prop));
}
Inline float32 f_prop_行字符串转小数(const S_Props& prop) {
	return f_字符串转F32(f_prop_LineStr(prop));
}

EngineAPI_EXPORT void f_prop_整数转行字符串(S_Props& prop, int32 value, const S_Props& 宽度, const S_Props& 填充字符, const S_Props& 字符方式);
EngineAPI_EXPORT void f_prop_小数转行字符串(S_Props& prop, float32 value, const S_Props& 宽度, const S_Props& 填充字符, const S_Props& 字符方式);
Inline S_Props f_prop_alloc_LineStrProp() {
	return f_alloc_LineStrProp(nullptr, u"用于编译");
}






struct S_PropContainer {
	std::vector<S_Props>	m_Item;
	uint64					m_当前项;
	fp_MapPtr元素更新		mf_元素变更;
};

Inline S_Props f_alloc_PropContainer(std::u16string name, E_值类型 值类型 = E_值类型::e_Type_PropContainer) {
	S_PropContainer* e = new S_PropContainer;
	e->m_当前项 = 0;
	e->mf_元素变更 = nullptr;
	//S_Props prop = { 值类型, (S_结构对象指针)e, name, {}, {nullptr}, 0, false, 0 };
	S_Props prop = f_prop_init(值类型, e, name, E_属性值映射方式::e_属性值映射_独立创建);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_Props f_alloc_SocketContainer(std::u16string name) {
	S_PropContainer* e = new S_PropContainer;
	e->m_当前项 = 0;
	e->mf_元素变更 = nullptr;

	//S_Props prop = { E_值类型::e_Type_SocketContainer, (S_结构对象指针)e, name, {}, {nullptr}, 0, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_SocketContainer, e, name, E_属性值映射方式::e_属性值映射_独立创建);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_Props f_alloc_PropLayout(std::u16string name, E_值类型 布局类型) {
	if (布局类型 < E_值类型::e_Type_LayoutBegin || 布局类型 > E_值类型::e_Type_LayoutEnd) return {};

	S_PropContainer* e = new S_PropContainer;
	e->m_当前项 = 0;
	e->mf_元素变更 = nullptr;
	//S_Props prop = { 布局类型, (S_结构对象指针)e, name, {}, {nullptr}, 0, false, 0 };
	S_Props prop = f_prop_init(布局类型, e, name, E_属性值映射方式::e_属性值映射_独立创建);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_PropContainer& f_prop_Container(S_Props& prop) {
	return *((S_PropContainer*)prop.m_Value);
}
Inline const S_PropContainer& f_prop_Container(const S_Props& prop) {
	return *((S_PropContainer*)prop.m_Value);
}






Inline S_Props f_alloc_PropArrayContainer(S_Array* data, std::u16string name, E_值类型 值类型) {
	//S_Props prop = { type, (S_结构对象指针)val, name, {}, {nullptr}, 0, false, 0 };
	S_Props prop = f_prop_init(值类型, data, name, E_属性值映射方式::e_属性值映射_独立创建);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_Array* f_prop_ArrayContainer(S_Props& prop) {
	return ((S_Array*)prop.m_Value);
}





struct S_PropList {
	std::list<S_Props>	m_Item;
	uint64				m_当前项;
	fp_MapPtr元素更新	mf_元素变更;
};

Inline S_Props f_alloc_PropList(std::u16string name) {
	S_PropList* e = new S_PropList;
	e->m_当前项 = 0;
	e->mf_元素变更 = nullptr;
	//S_Props prop = { E_值类型::e_Type_PropList, (S_结构对象指针)e, name, {}, {nullptr}, 0, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_PropList, e, name, E_属性值映射方式::e_属性值映射_独立创建);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_PropList& f_prop_PropList(S_Props& prop) {
	return *((S_PropList*)prop.m_Value);
}





typedef void(*fp_Operator)(void* ops);
typedef struct {
	void* m_Obj;
	fp_Operator	m_Func;
}S_Operator;
inline S_Operator* f_alloc_Ops(fp_Operator func, void* object) {
	S_Operator* ops = (S_Operator*)malloc(sizeof(S_Operator));
	ops->m_Func = func;
	ops->m_Obj = object;
	return ops;
}
inline void f_free_Ops(S_Operator* ops) {
	free(ops);
}



Inline S_Props f_alloc_OpsProp(fp_PropUpdate func, const std::u16string& name, const std::u16string& ico = u"") {
	S_Props prop = f_prop_init(E_值类型::e_Type_Operator, func, name, E_属性值映射方式::e_属性值映射_外部指针);
	DEF_alloc_Props_UI_Ptr(prop);
	prop.m_UI->m_Update = func;
	prop.m_风格属性 = new S_UI风格属性{ico, nullptr};
	return prop;
}

Inline S_Props f_alloc_对象回调Prop(fp_Operator func, void* object, const std::u16string& name) {
	S_Operator* ops = f_alloc_Ops(func, object);
	S_Props prop = f_prop_init(E_值类型::e_Type_ObjectOps, ops, name, E_属性值映射方式::e_属性值映射_外部指针);
	//S_Props prop = { E_值类型::e_Type_Operator, (S_结构指针)ops, name, nullptr, nullptr, {nullptr}, 0, false, 0 };
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}





inline S_Props f_propAlloc_RGB(vec3* data, std::u16string name) {
	E_属性值映射方式 值映射类型;
	if (data == nullptr) {
		data = (vec3*)malloc(sizeof(vec3));
		值映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	} 
	else 值映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	//S_Props prop = { E_值类型::e_Type_RGB, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 3, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_RGB, data, name, 值映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}


Inline S_Props f_propAlloc_RGBA(vec4* data, std::u16string name) {
	E_属性值映射方式 值映射类型;
	if (data == nullptr) {
		data = (vec4*)malloc(sizeof(vec4));
		值映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 值映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	//S_Props prop = { E_值类型::e_Type_RGBA, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 4, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_RGBA, data, name, 值映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}


EngineAPI_EXPORT S_Props f_alloc_曲线通道Prop(S_曲线通道* data, const std::u16string& name);

Inline S_曲线通道* f_prop_Curve(S_Props& prop) {
	return (S_曲线通道*)prop.m_Value;
}


EngineAPI_EXPORT S_Props f_alloc_2DCurveProp(S_曲线* data, const std::u16string& name);

Inline S_曲线* f_prop_2DCurve(S_Props& prop) {
	return (S_曲线*)prop.m_Value;
}
Inline const S_曲线* f_prop_2DCurve(const S_Props& prop) {
	return (S_曲线*)prop.m_Value;
}


EngineAPI_EXPORT S_Props f_alloc_动画曲线层Prop(S_动画曲线组* data, const std::u16string& name);



Inline S_Props f_alloc_纹理属性(S_TextueProp* data, const std::u16string& name) {
	E_属性值映射方式 值映射类型;
	if (data == nullptr) {
		data = (S_TextueProp*)malloc(sizeof(S_TextueProp));
		(*data) = { {}, {1,1}, 1, 0 };
		值映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}else 值映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	//S_Props prop = { E_值类型::e_Type_TexProp, (S_结构对象指针)value, name, {}, nullptr, {nullptr}, 0, false, 0 };
	S_Props prop = f_prop_init(E_值类型::e_Type_TexProp, data, name, 值映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_TextueProp& f_prop_TexProp(S_Props& prop) {
	return *((S_TextueProp*)prop.m_Value);
}
Inline S_TextueProp& f_prop_TexProp(const S_Props& prop) {
	return *((S_TextueProp*)prop.m_Value);
}



S_Props f_alloc_Prop纹理集(S_TextueSetsProp* data, const std::u16string& name);

Inline S_TextueSetsProp& f_prop_纹理集(S_Props& prop) {
	return *((S_TextueSetsProp*)prop.m_Value);
}
Inline S_TextueSetsProp& f_prop_纹理集(const S_Props& prop) {
	return *((S_TextueSetsProp*)prop.m_Value);
}




Inline S_Props f_alloc_物体属性(S_OBArray* value, const std::u16string& name) {
	if (value == nullptr) {
		value = (S_OBArray*)f_core_array_new(0, sizeof(S_物体*));
	}

	S_Props prop = { E_值类型::e_Type_Object_1D, (S_结构指针)value, name, {}, nullptr, {nullptr}, 0, false, 0 };
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_OBArray* f_prop_物体Prop(S_Props& prop) {
	return (S_OBArray*)prop.m_Value;
}






Inline S_Props f_alloc_键位(S_键位映射* value, const std::u16string& name) {
	assert(value);
	S_Props prop = { E_值类型::e_Type_键位映射, (S_结构指针)value, name, {}, nullptr, {nullptr}, 0, false, 0 };
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_键位映射* f_prop_键位(S_Props& prop) {
	return (S_键位映射*)prop.m_Value;
}
Inline const S_键位映射* f_prop_键位(const S_Props& prop) {
	return (const S_键位映射*)prop.m_Value;
}



Inline S_Props f_alloc_轨道(S_轨道* data, const DEF_WString& name) {
	E_属性值映射方式 值映射类型;
	if (data == nullptr) {
		data = new S_轨道;
		值映射类型 = E_属性值映射方式::e_属性值映射_独立创建;
	}
	else {
		值映射类型 = E_属性值映射方式::e_属性值映射_外部指针;
	}

	S_Props prop = f_prop_init(E_值类型::e_Type_轨道容器, data, name, 值映射类型);
	DEF_alloc_Props_UI_Ptr(prop);
	return prop;
}

Inline S_轨道& f_prop_轨道(S_Props& prop) {
	return *(S_轨道*)prop.m_Value;
}
Inline const S_轨道& f_prop_轨道(const S_Props& prop) {
	return *(S_轨道*)prop.m_Value;
}






EngineAPI_EXPORT S_Props f_prop_创建物体类型属性数据();
EngineAPI_EXPORT S_Props f_prop_创建图像格式类型属性数据();
EngineAPI_EXPORT S_Props f_prop_创建图像位宽类型属性数据();
EngineAPI_EXPORT S_Props f_prop_创建图像通道类型属性数据();
EngineAPI_EXPORT S_Props f_prop_创建写入方式属性数据();
EngineAPI_EXPORT S_Props f_prop_创建外部模型格式属性数据();

EngineAPI_EXPORT E_物体类型 f_prop_物体类型(const S_Props& prop);




Inline S_Props f_prop_属性引用(const S_Props& prop) {
	S_Props p = prop;
	p.m_值映射类型 = E_属性引用类型::e_引用;
	DEF_alloc_Props_UI_Ptr(p);
	p.m_私有 = false;
	p.m_UI->m_Update = prop.m_UI->m_Update;
	p.m_UI->m_关键帧 = prop.m_UI->m_关键帧;
	p.m_UI->m_Set = prop.m_UI->m_Set;
	return p;
}


Inline const uint8* f_解字符串(std::string& str, const uint8* data) {
	uint32 num = *((uint32*)data);
	data = &data[sizeof(uint32)];

	str.resize(num);
	memcpy(str.data(), data, num);

	return &data[num];
}

Inline void f_包字符串(S_UI8Array* 块, const std::string& str) {
	uint32 num = str.size();

	f_core_array_push_back_block((S_Array*)块, (uint8*)&num, sizeof(uint32));
	f_core_array_push_back_block((S_Array*)块, (uint8*)str.data(), num);
}


Inline const uint8* f_core_解字符串(std::u16string& str, const uint8* data) {
	uint32 num = *((uint32*)data);
	data = &data[sizeof(uint32)];

	str.resize(num);
	memcpy(str.data(), data, num);

	return &data[num];
}

Inline void f_core_包字符串(S_UI8Array* 块, const std::u16string& str) {
	uint32 num = str.size();

	f_core_array_push_back_block((S_Array*)块, (uint8*)&num, sizeof(uint32));
	f_core_array_push_back_block((S_Array*)块, (uint8*)str.data(), num, sizeof(uint16));
}






Inline const uint8* f_解宽字符串(std::u16string& str, const uint8* data) {
	uint32 num = *((uint32*)data);
	const uint16* strPtr = (uint16*)&(data[sizeof(uint32)]);

	str.resize(num);
	for (uint32 i = 0; i < num; ++i) {
		str[i] = strPtr[i];
	}
	return (uint8*)&strPtr[num];
}

Inline void f_包宽字符串(S_UI8Array* 块, const std::u16string& str) {
	uint32 num = str.size();

	f_core_array_push_back_block((S_Array*)块, (uint8*)&num, sizeof(uint32));
	f_core_array_push_back_block((S_Array*)块, (uint8*)str.data(), num * sizeof(uint16));
}

Inline void f_文件块_写字符串(S_UI8Array* 块, const std::u16string& str) {
	f_包宽字符串(块, str);
}
Inline const uint8* f_文件块_读字符串(const uint8* data, std::u16string& str) {
	return f_解宽字符串(str, data);
}

Inline void f_文件块_写字符串(S_UI8Array* 块, const std::string& str) {
	f_包字符串(块, str);
}
Inline const uint8* f_文件块_读字符串(const uint8* data, std::string& str) {
	return f_解字符串(str, data);
}


template<typename T>
const uint8* f_文件块_读数据块(const uint8* data_ptr, T& data) {
	data = *((T*)data_ptr);
	return &(data_ptr[sizeof(T)]);
}

template<typename T>
const void f_文件块_写数据块(S_UI8Array* 块, const T& data) {
	f_core_array_push_back_block((S_Array*)块, (uint8*)&data, sizeof(T));
}




Inline const uint8* f_文件块_读数据块2(uint8* data, const uint8* data_ptr, uint64 num) {
	memcpy(data, data_ptr, num);
	return &(data_ptr[num]);
}
Inline const uint8* f_文件块_读数据块(const uint8* data_ptr, uint8* data, uint64 num) {
	memcpy(data, data_ptr, num);
	return &(data_ptr[num]);
}
Inline void f_文件块_写数据块(S_UI8Array* 块, const uint8* data_ptr, uint64 num) {
	f_core_array_push_back_block((S_Array*)块, data_ptr, num);
}


Inline void f_文件块_写内存块(S_UI8Array* 块, const S_GPU内存块& mem) {
	f_文件块_写数据块(块, uint32(mem.m_Mem.m_数量));
	f_文件块_写数据块(块, f_bm_起始指针(mem), mem.m_Mem.m_数量 * mem.m_Buf->m_Offset);
}
Inline const uint8* f_文件块_读内存块(const uint8* 下一次读取数据指针, S_GPU内存块& mem) {
	uint32 num = 0;
	下一次读取数据指针 = f_文件块_读数据块(下一次读取数据指针, num);
	f_bm_resize(mem, num);
	return f_文件块_读数据块2(f_bm_起始指针(mem), 下一次读取数据指针, num * mem.m_Buf->m_Offset);
}



EngineAPI_EXPORT void			f_文件块_写入压缩数据(S_UI8Array* 块, const uint8* data, uint64 size);
EngineAPI_EXPORT const uint8*	f_文件块_读取压缩数据(const uint8* 下一次读取数据指针, uint8* data, uint64 size);


template<typename T>
Inline void f_文件块_写序列数据块(S_UI8Array* 块, const std::vector<T>& 要保存的数据, bool 是否压缩) {
	uint32 点数量 = 要保存的数据.size();
	f_文件块_写数据块(块, 点数量);

	if (是否压缩) {
		f_文件块_写入压缩数据(块, (uint8*)要保存的数据.data(), 点数量 * sizeof(T));
	}
	else {
		f_core_array_push_back_block((S_Array*)块, (uint8*)(要保存的数据.data()), 点数量 * sizeof(T));
	}
}

template<typename T>
Inline const uint8* f_文件块_读序列数据块(const uint8* 下一次读取数据指针, std::vector<T>& 要读取的数据, bool 是否压缩) {
	uint32 点数量 = 0;
	下一次读取数据指针 = f_文件块_读数据块(下一次读取数据指针, 点数量);

	要读取的数据.resize(点数量);
	if (是否压缩) {
		return f_文件块_读取压缩数据(下一次读取数据指针, (uint8*)要读取的数据.data(), 点数量 * sizeof(T));
	}
	
	return f_文件块_读数据块2((uint8*)(要读取的数据.data()), 下一次读取数据指针, 点数量 * sizeof(T));
}



Inline void f_文件块_写序列数据块(S_UI8Array* 块, const S_Array* 要保存的数据, bool 是否压缩) {
	uint32 点数量 = 要保存的数据->count;
	uint32 元素大小 = f_core_array_get_elt_size(要保存的数据);
	f_文件块_写数据块(块, 点数量);
	f_文件块_写数据块(块, 元素大小);

	if (是否压缩) {
		f_文件块_写入压缩数据(块, (uint8*)(要保存的数据->ptr_userData), uint64(点数量) * 元素大小);

		//uLongf 压缩后大小 = 点数量 * 元素大小;
		//std::vector<uint8> 压缩点(点数量 * 压缩后大小);
		//
		//compress((uint8*)压缩点.data(), &压缩后大小, 要保存的数据->ptr_userData, 压缩后大小);
		//
		//uint64 应对ZLIB这种纯类型 = 压缩后大小;
		//f_文件块_写数据块(块, 应对ZLIB这种纯类型);
		//f_core_array_push_back_block((S_Array*)块, (uint8*)压缩点.data(), 压缩后大小);
	}
	else {
		f_core_array_包(要保存的数据, 块);
	}
}

Inline const uint8* f_文件块_读序列数据块(const uint8* 下一次读取数据指针, S_Array* 要读取的数据, bool 是否压缩) {
	uint32 点数量 = 0;
	uint32 元素大小 = 0;
	下一次读取数据指针 = f_文件块_读数据块(下一次读取数据指针, 点数量);
	下一次读取数据指针 = f_文件块_读数据块(下一次读取数据指针, 元素大小);

	f_core_array_change_elt_size(要读取的数据, 元素大小);
	f_core_array_resize(要读取的数据, 点数量);
	
	if (是否压缩) {
		return f_文件块_读取压缩数据(下一次读取数据指针, (uint8*)要读取的数据->ptr_userData, uint64(点数量) * 元素大小);

		//uint64 压缩后大小 = 0;
		//下一次读取数据指针 = f_文件块_读数据块(压缩后大小, 下一次读取数据指针);
		//
		//uLongf 压缩前大小 = 点数量 * 元素大小;
		//uncompress(要读取的数据->ptr_userData, &压缩前大小, 下一次读取数据指针, 压缩后大小);
		//
		//return &(下一次读取数据指针[压缩后大小]);
	}

	return f_core_array_解(要读取的数据, 下一次读取数据指针);
}







CORE_ARRAY_HANDLE(S_StrArray, S_Props*)



